home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Views / Sources / USynchScroller.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  12.4 KB  |  407 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // USynchScroller.cp 
  3. // Copyright © 1989-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __USYNCHSCROLLER__
  7. #include "USynchScroller.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UCOMMAND__
  13. #include "UCommand.h"
  14. #endif
  15.  
  16. #ifndef __UDEBUG__
  17. #include "UDebug.h"
  18. #endif
  19.  
  20. #ifndef __UDOCUMENT__
  21. #include "UDocument.h"
  22. #endif
  23.  
  24. #ifndef __UEVENT__
  25. #include "UEvent.h"
  26. #endif
  27.  
  28. #ifndef __UFAILURE__
  29. #include "UFailure.h"
  30. #endif
  31.  
  32. #ifndef __UGEOMETRY__
  33. #include "UGeometry.h"
  34. #endif
  35.  
  36. #ifndef __UITERATOR__
  37. #include "UIterator.h"
  38. #endif
  39.  
  40. #ifndef __ULIST__
  41. #include "UList.h"
  42. #endif
  43.  
  44. #ifndef __UMACAPPGLOBALS__
  45. #include "UMacAppGlobals.h"
  46. #endif
  47.  
  48. #ifndef __UMACAPPUTILITIES__
  49. #include "UMacAppUtilities.h"
  50. #endif
  51.  
  52. #ifndef __UPATCH__
  53. #include "UPatch.h"
  54. #endif
  55.  
  56. #ifndef __UWINDOW__
  57. #include "UWindow.h"
  58. #endif
  59.  
  60. // Toolbox
  61.  
  62. #ifndef __DIALOGS__
  63. #include <Dialogs.h>
  64. #endif
  65.  
  66. // ANSI
  67.  
  68. #ifndef __STDIO__
  69. #include <stdio.h>
  70. #endif
  71.  
  72. #ifndef __STDLIB__
  73. #include <stdlib.h>
  74. #endif
  75.  
  76. //----------------------------------------------------------------------------------------
  77. // InitUSynchScroller: 
  78. //----------------------------------------------------------------------------------------
  79. #pragma segment SyncScrollInit
  80.  
  81. void InitUSynchScroller()
  82. {
  83. #if qTemplateViews
  84.     // Suppress Linker dead-stripping of these classes 
  85.     MA_REGISTER_CLASS(TPrimaryScroller);
  86.     MA_REGISTER_CLASS(TSecondaryScroller);
  87. #endif
  88. } // InitUSynchScroller 
  89.  
  90.  
  91. //========================================================================================
  92. // CLASS TPrimaryScroller
  93. //========================================================================================
  94. #undef Inherited
  95. #define Inherited TScroller
  96.  
  97. #pragma segment SyncScrollNonRes
  98. MA_DEFINE_CLASS_M1(TPrimaryScroller, Inherited);
  99.  
  100. //----------------------------------------------------------------------------------------
  101. // TPrimaryScroller constructor
  102. //----------------------------------------------------------------------------------------
  103. #pragma segment SyncScrollNonRes
  104.  
  105. TPrimaryScroller::TPrimaryScroller()
  106. {
  107.     fSecondaryScrollers = NULL;
  108. } // TPrimaryScroller::TPrimaryScroller
  109.  
  110. //----------------------------------------------------------------------------------------
  111. // TPrimaryScroller::IPrimaryScroller: 
  112. //----------------------------------------------------------------------------------------
  113. #pragma segment SyncScrollNonRes
  114.  
  115. void TPrimaryScroller::IPrimaryScroller(TView* itsSuperView,
  116.                                  const VPoint& itsLocation,
  117.                                  const VPoint& itsSize,
  118.                                  SizeDeterminer itsHSizeDet,
  119.                                  SizeDeterminer itsVSizeDet,
  120.                                  const VPoint& itsMax,
  121.                                  Boolean wantHorzSBar,
  122.                                  Boolean wantVertSBar)
  123.  
  124. {
  125.     this->IScroller(itsSuperView, itsLocation, itsSize,
  126.                     itsHSizeDet, itsVSizeDet, itsMax,wantHorzSBar, wantVertSBar);
  127. } // TPrimaryScroller::IPrimaryScroller
  128.  
  129. //----------------------------------------------------------------------------------------
  130. // TPrimaryScroller::Free: 
  131. //----------------------------------------------------------------------------------------
  132. #pragma segment SyncScrollNonRes
  133.  
  134. TPrimaryScroller::~TPrimaryScroller()
  135. {
  136.     {
  137.         CObjectIterator iter(fSecondaryScrollers);
  138.         TSecondaryScroller* aSecondaryScroller;
  139.     
  140.         for (aSecondaryScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aSecondaryScroller = (TSecondaryScroller*) iter.NextObject())
  141.             this->RemoveSecondaryScroller(aSecondaryScroller);
  142.     }
  143.     fSecondaryScrollers = (TList *)FreeIfObject(fSecondaryScrollers);
  144. } // TPrimaryScroller::Free 
  145.  
  146. //----------------------------------------------------------------------------------------
  147. // TPrimaryScroller::AddSecondaryScroller: 
  148. //----------------------------------------------------------------------------------------
  149. #pragma segment SyncScrollNonRes
  150.  
  151. void TPrimaryScroller::AddSecondaryScroller(TSecondaryScroller* itsSecondaryScroller,
  152.                                                    VCoordinate itsHDependency,
  153.                                                    VCoordinate itsVDependency)
  154. {
  155.     if (itsSecondaryScroller)
  156.     {
  157.         itsSecondaryScroller->fPrimaryScroller = this;
  158.         itsSecondaryScroller->fDeltaFactor = VPoint(itsHDependency, itsVDependency).ToPoint();
  159.  
  160.         if (!fSecondaryScrollers)
  161.             fSecondaryScrollers = NewList();
  162.  
  163.         fSecondaryScrollers->Insert(itsSecondaryScroller);
  164.     }
  165. } // TPrimaryScroller::AddSecondaryScroller 
  166.  
  167. //----------------------------------------------------------------------------------------
  168. // TPrimaryScroller::RemoveSecondaryScroller: 
  169. //----------------------------------------------------------------------------------------
  170. #pragma segment SyncScrollNonRes
  171.  
  172. void TPrimaryScroller::RemoveSecondaryScroller(TSecondaryScroller* itsSecondaryScroller)
  173. {
  174.     if (itsSecondaryScroller)
  175.     {
  176.         itsSecondaryScroller->fPrimaryScroller = NULL;
  177.         if (fSecondaryScrollers)
  178.         {
  179.             fSecondaryScrollers->Delete(itsSecondaryScroller);
  180.             if (fSecondaryScrollers->IsEmpty())
  181.                 fSecondaryScrollers = (TList *)FreeIfObject(fSecondaryScrollers);
  182.         }
  183.     }
  184. } // TPrimaryScroller::RemoveSecondaryScroller 
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // TPrimaryScroller::DoScroll: 
  188. //----------------------------------------------------------------------------------------
  189. #pragma segment SyncScrollRes
  190.  
  191. void TPrimaryScroller::DoScroll(const VPoint& delta,
  192.                                        Boolean redraw)// override 
  193. {
  194.     {
  195.         CObjectIterator iter(fSecondaryScrollers);
  196.         TSecondaryScroller* aSecondaryScroller;
  197.     
  198.         for (aSecondaryScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aSecondaryScroller = (TSecondaryScroller*) iter.NextObject())
  199.         {
  200.             VPoint itsDelta(delta);
  201.         
  202.             for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  203.                 if (aSecondaryScroller->fDeltaFactor[vhs])    // kVDependent or kHDependent 
  204.                 {
  205.                     if (itsDelta[vhs] < 0)
  206.                     {
  207.                         itsDelta[vhs] = Max(itsDelta[vhs], -aSecondaryScroller->fTranslation[vhs]);
  208.                     }
  209.                     else if (itsDelta[vhs] > 0)
  210.                     {
  211.                         itsDelta[vhs] = Min(itsDelta[vhs], aSecondaryScroller->fMaxTranslation[vhs] - aSecondaryScroller->fTranslation[vhs]);
  212.                     }
  213.                     aSecondaryScroller->fTranslation[vhs] += itsDelta[vhs];
  214.                 }
  215.         
  216.             if (itsDelta != gZeroVPt)
  217.             {
  218.                 aSecondaryScroller->InvalidateFocus();    // You never know who might call 
  219.                 aSecondaryScroller->InvalidateCoordinates();
  220.             }
  221.         }
  222.     }
  223.  
  224.     Inherited::DoScroll(delta, redraw);
  225. } // TPrimaryScroller::DoScroll 
  226.  
  227. //----------------------------------------------------------------------------------------
  228. // TPrimaryScroller::ScrollDraw: 
  229. //----------------------------------------------------------------------------------------
  230. #pragma segment SyncScrollRes
  231.  
  232. void TPrimaryScroller::ScrollDraw(const VPoint& delta,
  233.                                          Boolean invalidate)// override 
  234. {
  235.     if (fSuperView->IsDrawable())
  236.     {
  237.         CTemporaryRegion scrollRgn;
  238.  
  239.         this->GetExtentRegion(scrollRgn);
  240.         this->LocalToSuperRegion(scrollRgn);
  241.  
  242.         CRect superVisRect((*GetClipRegion(qd.thePort))->rgnBBox); // just test the clip, it's faster
  243.  
  244. #if qDebug
  245.         if (gIntenseDebugging)
  246.             WriteFocus();
  247. #endif
  248.  
  249.         const VRect visVRect(superVisRect);
  250.         if (((visVRect - delta) & visVRect).Empty()) // too far to scrollrect 
  251.         {
  252.             this->ForceRedraw();
  253.  
  254.             CObjectIterator iter(fSecondaryScrollers);
  255.             TSecondaryScroller* aScroller;
  256.         
  257.             for (aScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aScroller = (TSecondaryScroller*) iter.NextObject())
  258.             {
  259.                 if (aScroller->IsShown ())
  260.                 {
  261.                     if (delta.v && (aScroller->fDeltaFactor.v == kVDependent))
  262.                         aScroller->ForceRedraw();
  263.                     else if (delta.h && (aScroller->fDeltaFactor.h == kHDependent))
  264.                         aScroller->ForceRedraw();
  265.                 }
  266.             }
  267.         }
  268.         else        // Can use ScrollRect
  269.         {
  270.             CTemporaryRegion tempRgn;
  271.  
  272. #if qDebug
  273.             fSuperView->AssumeFocused();
  274. #endif
  275.  
  276.             {        // for correct failure handling
  277.                 CObjectIterator iter(fSecondaryScrollers);
  278.                 TSecondaryScroller* aScroller;
  279.             
  280.                 for (aScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aScroller = (TSecondaryScroller*) iter.NextObject())
  281.                 {
  282.                     if (aScroller->IsShown ())
  283.                     {
  284.                         CPoint localDeltaFactor(aScroller->fDeltaFactor);
  285.                     
  286.                         CRect frameRect(aScroller->fSuperView->ViewToQDRect(aScroller->GetFrame()));
  287.                         // main scroller is moving both directions but dependent can only move in v
  288.                         if (delta.h && delta.v && (localDeltaFactor.h == kNotHDependent) && (localDeltaFactor.v == kVDependent))
  289.                         {
  290.                             ScrollRect(frameRect, 0, (short) - delta.v, tempRgn);
  291.                             aScroller->fSuperView->InvalidateRegion(tempRgn);
  292.                         }
  293.                         // main scroller is moving both directions but dependent can only move in h
  294.                         else if (delta.h && delta.v && (localDeltaFactor.h == kHDependent) && (localDeltaFactor.v == kNotVDependent))
  295.                         {
  296.                             ScrollRect(frameRect, (short) - delta.h, 0, tempRgn);
  297.                             aScroller->fSuperView->InvalidateRegion(tempRgn);
  298.                         }
  299.                         // main scroller is moving in either direction and dependent can follow
  300.                         else if ((delta.h && (localDeltaFactor.h == kHDependent)) || (delta.v && (localDeltaFactor.v == kVDependent)))
  301.                         {
  302.                             aScroller->GetExtentRegion(tempRgn);
  303.                             aScroller->LocalToSuperRegion(tempRgn);
  304.                             UnionRgn(scrollRgn, tempRgn, scrollRgn);
  305.                         }
  306.                     }
  307.                 }
  308.             }
  309.  
  310. #if qDebug
  311.             fSuperView->AssumeFocused();
  312. #endif
  313.  
  314.             // Now, we've either scrolled any dependent scrollers that can't scroll with
  315.             // us or we've accumulated their frames in scrollRgn.  By clipping to the
  316.             // accumulated region we can just scroll the entire superview and the right
  317.             // stuff should happen. (Cross fingers)
  318.             SectRgn(scrollRgn, qd.thePort->clipRgn, scrollRgn);
  319.  
  320.             // Get clip so we can restore it later and keep from having
  321.             // to invalidate the superview's focus
  322.             GetClip(tempRgn);
  323.  
  324.             SetClip(scrollRgn);
  325.             ScrollRect(superVisRect, (short) - delta.h, (short) - delta.v, scrollRgn);
  326.  
  327.             // restore the clip so we don't have to invalidate the focus
  328.             SetClip(tempRgn);
  329.  
  330.             fSuperView->InvalidateRegion(scrollRgn);
  331.         }
  332.  
  333.         if (!invalidate)
  334.             fSuperView->Update();
  335.     }
  336. } // TPrimaryScroller::ScrollDraw 
  337.  
  338.  
  339.  
  340. //========================================================================================
  341. // CLASS TSecondaryScroller
  342. //========================================================================================
  343. #undef Inherited
  344. #define Inherited TScroller
  345.  
  346. #pragma segment SyncScrollNonRes
  347. MA_DEFINE_CLASS_M1(TSecondaryScroller, Inherited);
  348.  
  349. //----------------------------------------------------------------------------------------
  350. // TSecondaryScroller constructor
  351. //----------------------------------------------------------------------------------------
  352. #pragma segment SyncScrollNonRes
  353.  
  354. TSecondaryScroller::TSecondaryScroller()
  355. {
  356.     fPrimaryScroller = NULL;
  357.     fDeltaFactor = CPoint(kNotHDependent, kNotVDependent);
  358. } // TSecondaryScroller::TSecondaryScroller
  359.  
  360. //----------------------------------------------------------------------------------------
  361. // TSecondaryScroller::ISecondaryScroller: 
  362. //----------------------------------------------------------------------------------------
  363. #pragma segment SyncScrollNonRes
  364.  
  365. void TSecondaryScroller::ISecondaryScroller(TView* itsSuperView,
  366.                                  const VPoint& itsLocation,
  367.                                  const VPoint& itsSize,
  368.                                  SizeDeterminer itsHSizeDet,
  369.                                  SizeDeterminer itsVSizeDet,
  370.                                  const VPoint& itsMax,
  371.                                  Boolean wantHorzSBar,
  372.                                  Boolean wantVertSBar)
  373.  
  374. {
  375.     this->IScroller(itsSuperView, itsLocation, itsSize,
  376.                     itsHSizeDet, itsVSizeDet, itsMax,wantHorzSBar, wantVertSBar);
  377. } // TSecondaryScroller::ISecondaryScroller
  378.  
  379. //----------------------------------------------------------------------------------------
  380. // TSecondaryScroller::Free: 
  381. //----------------------------------------------------------------------------------------
  382. #pragma segment SyncScrollNonRes
  383.  
  384. TSecondaryScroller::~TSecondaryScroller()
  385.  
  386. {
  387.     if (fPrimaryScroller)
  388.         fPrimaryScroller->RemoveSecondaryScroller(this);    // sets fPrimaryScroller to NULL
  389. } // TSecondaryScroller::Free 
  390.  
  391. //----------------------------------------------------------------------------------------
  392. // TSecondaryScroller::DoScroll: 
  393. //----------------------------------------------------------------------------------------
  394. #pragma segment SyncScrollRes
  395.  
  396. void TSecondaryScroller::DoScroll(const VPoint& delta,
  397.                                          Boolean redraw)// override 
  398. {
  399.     if (fPrimaryScroller)
  400.         fPrimaryScroller->ScrollBy( VPoint( fDeltaFactor.h * delta.h, fDeltaFactor.v * delta.v), redraw);
  401. } // TSecondaryScroller::DoScroll 
  402.  
  403. //----------------------------------------------------------------------------------------
  404. // End of USynchScroller.cp
  405.  
  406. #pragma segment Inline
  407.